#include "./i2c/soft_i2c.h"

void I2C_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
  
  I2C_SDA_GPIO_CLK();
  I2C_SCL_GPIO_CLK();
  
  GPIO_InitStruct.Mode    = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Speed   = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.Pull    = GPIO_PULLUP;
	
	GPIO_InitStruct.Pin 		= I2C_SDA_GPIO_PIN;
	HAL_GPIO_Init(I2C_SDA_GPIO_PORT,&GPIO_InitStruct);
	
	GPIO_InitStruct.Pin 		= I2C_SCL_GPIO_PIN;
	HAL_GPIO_Init(I2C_SCL_GPIO_PORT,&GPIO_InitStruct);
	
	I2C_SDA_H;
	I2C_SCL_H;
}

/*Լ us*/
void I2C_Delay(void)
{
	for(uint32_t i = 0;i < 500;i++)
	{
		__nop();
	}
}

void I2C_Start(void)
{
	I2C_SCL_H;
	I2C_SDA_H;
	I2C_Delay();
	I2C_SDA_L;
	I2C_Delay();
	
	//钳住总线为忙状态，禁止其它设备占用
	I2C_SCL_L;
}

void I2C_Stop(void)
{
	I2C_SCL_H;
	I2C_SDA_L;
	I2C_Delay();
	I2C_SDA_H;
	I2C_Delay();
}

void I2C_ACK(void)
{
	I2C_SDA_L;
	I2C_Delay();
	I2C_SCL_H;
	I2C_Delay();
	I2C_SCL_L;
	I2C_Delay();
	I2C_SDA_H;
}

void I2C_NAK(void)
{
	I2C_SDA_H;
	I2C_Delay();
	I2C_SCL_H;
	I2C_Delay();
	I2C_SCL_L;
	I2C_Delay();
}

int32_t I2C_RecvAck(void)
{
	int32_t ret = 0;
	
	I2C_SDA_H;
	I2C_SCL_H;
	I2C_Delay();
	
	if(I2C_SDA)
	{
		//NAK
		ret = -1;
	}
	else
	{
		//ACK
		ret = 0;
	}
	
	I2C_SCL_L;
	I2C_Delay();
	
	return ret;
}

void I2C_SendByte(uint8_t c)
{
	for(uint32_t i = 0;i < 8;i++)
	{
		if(c & 0x80)
		{
			I2C_SDA_H;
		}
		else
		{
			I2C_SDA_L;
		}
		c <<= 1UL;
		
		I2C_SCL_H;
		I2C_Delay();
		I2C_SCL_L;
		I2C_Delay();
	}
}

uint8_t I2C_ReadByte(void)
{
	uint8_t ret = 0;
	
	for(uint32_t i = 0;i < 8;i++)
	{
		I2C_Delay();
		I2C_SCL_H;
		
		if(I2C_SDA)
		{
//			ret |= (uint8_t)(1 << i);//LSB
			ret |= ((uint8_t)0x80 >> i);//MSB
		}
		else
		{
//			ret &= (~(uint8_t)(1 << i));//LSB
			ret &= (~(uint8_t)0x80 >> i);//MSB
		}
		
		I2C_Delay();
		I2C_SCL_L;
	}
	
	return ret;
}

int32_t I2C_CheckDevice(uint8_t devAddr)
{
	int32_t ret = 0;
	
	I2C_Start();
	
	I2C_SendByte((devAddr << 1UL) | (uint8_t)0x00);
	ret = I2C_RecvAck();
	
	I2C_Stop();
	
	return ret;
}

void HAL_WriteByte(uint8_t devAddr,uint8_t addr,uint8_t c)
{
	I2C_Start();
	
	I2C_SendByte((devAddr << 1UL) | (uint8_t)0x00);
	I2C_RecvAck();
	I2C_SendByte(addr);
	I2C_RecvAck();
	I2C_SendByte(c);
	I2C_RecvAck();
	
	I2C_Stop();
}

uint8_t HAL_ReadByte(uint8_t devAddr,uint8_t addr)
{
	uint8_t ret = 0;
	
	I2C_Start();
	
	I2C_SendByte((devAddr << 1UL) | (uint8_t)0x00);
	I2C_RecvAck();
	I2C_SendByte(addr);
	I2C_RecvAck();
	
	I2C_Start();
	
	I2C_SendByte((devAddr << 1UL) | (uint8_t)0x01);
	I2C_RecvAck();
	ret = I2C_ReadByte();
	I2C_NAK();
	
	I2C_Stop();
	
	return ret;
}

void HAL_ReadBytes(uint8_t devAddr,uint8_t addr,uint8_t *pBuf,uint32_t size)
{
	I2C_Start();
	
	I2C_SendByte((devAddr << 1UL) | (uint8_t)0x00);
	I2C_RecvAck();
	I2C_SendByte(addr);
	I2C_RecvAck();
	
	I2C_Start();
	
	I2C_SendByte((devAddr << 1UL) | (uint8_t)0x01);
	I2C_RecvAck();
	for(uint32_t i = 0;i < size;i++)
	{
		pBuf[i] = I2C_ReadByte();
		if(i == (size - 1))
		{
			I2C_NAK();
		}
		else
		{
			I2C_ACK();
		}
	}
	
	I2C_Stop();
}
